package com.liry.mybatis.datascope;

import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.reflection.property.PropertyNamer;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字段映射
 * 注：该工具是基于mybatis-plus来的，支持mybatis-plus 3.5.0 +
 *
 * @author ALI
 * @since 2022/06/11
 */
public class MybatisPlusUtil {

    private MybatisPlusUtil() {

    }

    /**
     * 获取 数据库字段
     *
     * @param column lambda表达式
     * @return 数据库字段名
     */

    public static <T> String getColumn(SFunction<T, ?> column) {
        LambdaMeta lambda = LambdaUtils.extract(column);
        Class<?> aClass = lambda.getInstantiatedClass();
        String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(aClass);
        ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName));
        return columnCache.getColumn();
    }

    public static <T> String getTableName(Class<T> clazz) {
        TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
        if (tableInfo != null) {
            return tableInfo.getTableName();
        }
        return null;
    }

    public static List<String> getTableColumns(String tableName) {
        if (StringUtils.isBlank(tableName)) {
            return Collections.emptyList();
        }
        TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
        if (tableInfo != null) {
            return checkIdField(tableInfo);
        }
        TableInfo temp = TableInfoHelper.getTableInfo(tableName.toUpperCase());
        if (temp != null) {
            return checkIdField(temp);
        }

        return Collections.emptyList();
    }

    private static List<String> checkIdField(TableInfo tableInfo) {
        List<String> result = tableInfo.getFieldList().stream().map(TableFieldInfo::getColumn).collect(Collectors.toList());
        String idField = tableInfo.getKeyColumn();
        if (!StringUtils.isBlank(idField)) {
            result.add(idField);
        }
        return result;
    }

    /**
     * 根据实体类获取数据库字段映射
     *
     * @param clazz     实体类
     * @param fieldName 实体字段
     * @return 数据库字段
     */
    public static String getColumn(Class<?> clazz, String fieldName) {
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(clazz);
        ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName));
        return columnCache.getColumn();
    }
}
